export default class Snake {
  // //获取整个蛇的元素
  // element: HTMLElement;
  // constructor() {
  //   this.element = document.getElementById("snake")!;
  // }
  //整个蛇的容器
  element: HTMLElement;
  //蛇头
  head: HTMLElement;
  //蛇身
  bodies: HTMLCollection;
  //HTML DOM 中的 HTMLCollection 是即时更新的（live）；当其所包含的文档结构发生改变时，它会自动更新。因此，最好是创建副本（例如，使用 Array.from）后再迭代这个数组以添加、移动或删除 DOM 节点
  constructor() {
    this.element = document.getElementById("snake")!;
    this.head = document.querySelector("#snake > div") as HTMLElement; //类型断言
    this.bodies = this.element.getElementsByTagName("div")!;
  }

  /**
   * 这个get   set   是语法糖
   * let snake = new Snake();
   * 直接snake.X 就可以访问
   */

  //获取蛇头的坐标
  get X() {
    return this.head.offsetLeft;
  }
  get Y() {
    return this.head.offsetTop;
  }

  //设置蛇头的坐标
  set X(value: number) {
    if (this.X === value) {
      return;
    }
    if (value < 0 || value > 290) {
      throw new Error("🐍蛇撞墙了");
    }
    //判断蛇是不是在掉头
    //第二节身体存在 且蛇头要移动的位置和第二节身体的位置一样的话就是在掉头
    if (
      this.bodies[1] &&
      (this.bodies[1] as HTMLElement).offsetLeft === value
    ) {
      if (value > this.X) {
        value = this.X - 10;
      } else {
        value = this.X + 10;
      }
    }
    this.moveBody();
    this.head.style.left = value + "px";
    this.checkCrush();
  }
  set Y(value: number) {
    if (this.Y === value) {
      return;
    }
    if (value < 0 || value > 290) {
      throw new Error("🐍撞墙了");
    }
    if (this.bodies[1] && (this.bodies[1] as HTMLElement).offsetTop === value) {
      if (value > this.Y) {
        value = this.Y - 10;
      } else {
        value = this.Y + 10;
      }
    }
    this.moveBody(); //在移动头尾时也是一样的道理  要先动尾巴再动头
    this.head.style.top = value + "px";
    this.checkCrush();
  }

  //设置蛇增加身体的方法
  addBody() {
    //向element中添加一个div
    this.element.insertAdjacentHTML("beforeend", "<div></div>");
  }
  //移动身体
  moveBody() {
    //移动身体时
    //从尾巴往头改  不然前面改了后面就找不到了
    //遍历获取所有的身体 从尾巴到第二截儿  从尾部遍历
    console.log("this.bodies.length", this.bodies.length);
    console.log("this.bodies", this.bodies);
    for (let i = this.bodies.length - 1; i > 0; i--) {
      //获取到前一个位置的身体的位置
      let X = (this.bodies[i - 1] as HTMLElement).offsetLeft;
      let Y = (this.bodies[i - 1] as HTMLElement).offsetTop;

      //将前一个身体的位置赋值给当前的身体
      (this.bodies[i] as HTMLElement).style.left = X + "px";
      (this.bodies[i] as HTMLElement).style.top = Y + "px";
    }
  }
  //检查身体碰撞
  checkCrush() {
    //获取所有身体，检查师傅和蛇头重叠了
    for (let i =  1; i <this.bodies.length ; i++) {
      if (
        this.X === (this.bodies[i] as HTMLElement).offsetLeft &&
        this.Y === (this.bodies[i] as HTMLElement).offsetTop
      ) {
        throw new Error("蛇撞到了自己");
      }
    }
  }
}
